<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <title>Switch Media Devices</title>
        <link href="../assets/bootstrap.min.css" rel="stylesheet">
        <link href="../assets/index.css" rel="stylesheet">
    </head>

    <body>

        <nav class="container-fluid demo-nav">
            <div>Qiniu RTC Web SDK API Demos</div>
            <a class="navbar-brand" href="https://github.com/pili-engineering/QNRTC-Web">
                <svg height="32" viewBox="0 0 16 16" version="1.1" width="32" aria-hidden="true">
                    <path fill-rule="evenodd"
                        d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z">
                    </path>
                </svg>
            </a>
        </nav>

        <div class="container">
            <form>
                <div class="mb-3">
                    <label class="form-label" for="room-token"> Room Token </label>
                    <input type="text" class="form-control" id="room-token" required>
                    <div class="form-text">
                        Don't know how to create a token? Refer to this <a
                            href="https://developer.qiniu.com/rtc/8813/roomToken">doc</a>
                    </div>
                    <label for="camera-select">Cameras</label>
                    <select class="form-select" id="camera-select"></select>
                    <label for="microphone-select">Microphones</label>
                    <select class="form-select" id="microphone-select"></select>
                    <label for="playbackDevice-select">Playback Devices</label>
                    <select class="form-select" id="playbackDevice-select"></select>
                </div>
                <button class="btn btn-primary" id="join-room-btn">Join</button>
                <button class="btn btn-primary" disabled id="leave-room-btn">Leave</button>
            </form>
        </div>

        <div class="container" id="media-container"></div>

        <script src="../assets/bootstrap.bundle.min.js"></script>
        <script src="../assets/qnweb-rtc.js"></script>
        <script src="../assets/index.js"></script>

        <script>
            const client = QNRTC.createClient();

            const joinRoomBtn = document.getElementById("join-room-btn");
            const leaveRoomBtn = document.getElementById("leave-room-btn");
            const roomTokenInput = document.getElementById("room-token");
            const mediaContainer = document.getElementById("media-container");
            const cameraSelect = document.getElementById("camera-select");
            const microphoneSelect = document.getElementById("microphone-select");
            const playbackDeviceSelect = document.getElementById("playbackDevice-select");

            let cameras = [];
            let microphones = [];
            let playbackDevices = [];

            function createSelectOption(label, deviceId) {
                const option = document.createElement("option");
                option.value = deviceId;
                option.innerText = label;
                return option;
            }

            function updateDeviceSelect(devices, selectElement) {
                selectElement.innerHTML = "";
                selectElement.appendChild(createSelectOption("-", "-"));
                for (const device of devices) {
                    selectElement.appendChild(createSelectOption(device.label, device.deviceId));
                }
            }

            function getCameras() {
                QNRTC.getCameras()
                    .then(devices => {
                        cameras = devices;
                        updateDeviceSelect(devices, cameraSelect);
                    })
                    .catch(e => {
                        alert(e.message, "error");
                    });
            }

            function getMicrophones() {
                QNRTC.getMicrophones()
                    .then(devices => {
                        microphones = devices;
                        updateDeviceSelect(devices, microphoneSelect);
                    })
                    .catch(e => {
                        alert(e.message, "error");
                    });
            }

            function getPlaybackDevices() {
                QNRTC.getPlaybackDevices()
                    .then(devices => {
                        playbackDevices = devices;
                        updateDeviceSelect(devices, playbackDeviceSelect);
                    })
                    .catch(e => {
                        alert(e.message, "error");
                    });
            }

            getCameras();
            getMicrophones();
            getPlaybackDevices();

            /**
             * 监听设备变化事件，然后再次设备列表
             */

            QNRTC.onCameraChanged = (info) => {
                console.log("camera changed", info);
                getCameras();
            };

            QNRTC.onMicrophoneChanged = (info) => {
                console.log("microphone changed", info);
                getMicrophones();
            };

            QNRTC.onPlaybackDeviceChanged = (info) => {
                console.log("playback device changed", info);
                getPlaybackDevices();
            };

            let localTracks = [];

            async function handleUserPublished(userID, tracks) {
                try {
                    const { videoTracks, audioTracks } = await client.subscribe(tracks);
                    playUserTracks([...videoTracks, ...audioTracks]);
                } catch (e) {
                    alert(e.message, "warning");
                }
            }

            function playUserTracks(tracks) {
                for (const track of tracks) {
                    if (track.isAudio()) {
                        track.play(document.body)
                            .then(() => {
                                if (playbackDeviceSelect.value !== "-") {
                                    return track.setPlaybackDevice(playbackDeviceSelect.value);
                                }
                            })
                            .catch(e => {
                                alert(e.message, "warning");
                            });
                    } else {
                        const div = document.createElement("div");
                        if (track.trackID) div.id = track.trackID;
                        mediaContainer.appendChild(div);
                        track.play(div)
                            .catch(e => {
                                alert(e.message, "warning");
                            });
                    }
                }
            }

            function handleUserUnPublished(userID, tracks) {
                for (const track of tracks) {
                    let div = document.getElementById(track.trackID);
                    if (div) div.remove();
                }
            }

            joinRoomBtn.onclick = async (e) => {
                e.preventDefault();

                try {
                    client.on("user-published", handleUserPublished);
                    client.on("user-unpublished", handleUserUnPublished);
                    await client.join(roomTokenInput.value);

                    // 根据指定的设备 id 来完成采集
                    localTracks = await QNRTC.createMicrophoneAndCameraTracks(
                        { microphoneId: microphoneSelect.value === "-" ? undefined : microphoneSelect.value },
                        { cameraId: cameraSelect.value === "-" ? undefined : cameraSelect.value },
                    );

                    for (const track of localTracks) {
                        if (track.isVideo()) {
                            playUserTracks([track]);
                        }
                    }
                    await client.publish(localTracks);

                    joinRoomBtn.disabled = true;
                    leaveRoomBtn.disabled = false;
                } catch (e) {
                    alert(e.message, "warning");
                }
            };

            leaveRoomBtn.onclick = (e) => {
                e.preventDefault();
                client.leave()
                    .then(() => {
                        for (const track of localTracks) {
                            track.destroy();
                        }
                        localTracks = [];
                        mediaContainer.innerHTML = "";
                        joinRoomBtn.disabled = false;
                        leaveRoomBtn.disabled = true;
                    })
                    .catch((e) => {
                        alert(e.message, "warning");
                    });
            }

        </script>

    </body>

</html>